package service

import (
	"context"
	"errors"

	v1 "server_go/api/v1"
	"server_go/internal/model"
	"server_go/internal/repository"

	"time"

	"fmt"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type AdiminService interface {
	Login(ctx context.Context, req v1.AdiminRequest) (string, error)
	CreateUser(ctx context.Context, req v1.AdiminCreateUserRequest) error
	DeleteUser(ctx context.Context, userId uint) error
	ResetPassword(ctx context.Context, req v1.ResetPasswordRequest, userId uint) error
	QueryAllUser(ctx context.Context) ([]v1.QueryAllUserResponse, error)
}

func NewAdiminService(
	service *Service,
	adiminRepository repository.AdiminRepository,
) AdiminService {
	return &adiminService{
		Service:          service,
		adiminRepository: adiminRepository,
	}
}

type adiminService struct {
	*Service
	adiminRepository repository.AdiminRepository
}

func (s *adiminService) Login(ctx context.Context, req v1.AdiminRequest) (string, error) {
	if req.Account == "" || req.Password == "" {
		return "", v1.ErrBadRequest
	}
	adimin, err := s.adiminRepository.GetAdiminByAccount(ctx, req.Account)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return "", v1.ErrAdiminNotFound
		}
		return "", v1.ErrInternalServerError
	}

	if adimin.Type != model.AdiminType {
		return "", v1.ErrType
	}
	err = bcrypt.CompareHashAndPassword([]byte(adimin.Password), []byte(req.Password))
	if err != nil {
		return "", v1.ErrPwd
	}
	fmt.Println(adimin.ID)
	token, _ := s.jwt.GenToken(adimin.ID, time.Now().Add(time.Hour*24*7), model.AdiminType)
	return token, nil

}
func (s *adiminService) CreateUser(ctx context.Context, req v1.AdiminCreateUserRequest) error {
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	password := string(hashedPassword)
	_, err = s.adiminRepository.CreateUser(ctx, req.Account, password, req.Name)
	if err != nil {
		return err
	}
	return nil
}
func (s *adiminService) DeleteUser(ctx context.Context, userId uint) error {
	err := s.tm.Transaction(ctx, func(ctx context.Context) error {
		_, err := s.adiminRepository.GetUserById(ctx, userId)
		if err != nil {
			return v1.ErrAdiminNotFound
		}
		err = s.adiminRepository.DeleteUser(ctx, userId)
		if err != nil {
			return err
		}
		return nil

	})

	if err != nil {

		return err
	}
	return nil
}

// 重置密码
func (s *adiminService) ResetPassword(ctx context.Context, req v1.ResetPasswordRequest, userId uint) error {
	_, err := s.adiminRepository.GetUserById(ctx, userId)
	if err != nil {
		return v1.ErrAdiminNotFound
	}
	if req.Password == "" {
		req.Password = "123456"
	}
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	ResetPassword := string(hashedPassword)
	err = s.adiminRepository.ResetPassword(ctx, userId, ResetPassword)
	return err
}

// 查询用户
func (s *adiminService) QueryAllUser(ctx context.Context) ([]v1.QueryAllUserResponse, error) {
	users, err := s.adiminRepository.QueryAllUser(ctx)
	if err != nil {
		return nil, err
	}
	var res []v1.QueryAllUserResponse
	for _, user := range users {
		res = append(res, v1.QueryAllUserResponse{
			ID:   user.ID,
			Name: user.Name,
		})
	}
	return res, nil

}
